package com.cskaoyan.javase.oop1._1basic;

/**
 * 这里给出一个案例：
 * 创建学生对象，然后使用访问学生对象的属性，使用学生对象的行为。
 *
 * 以上需求,需要创建学生对象,首先需要创建对象的模板---类
 * 如何创建类?
 * 定义类包括定义类本身，和定义类中结构两部分。
 * 1.定义类结构本身
 * 语法:
 * [类修饰符列表] class 类名{
 *   // 类体
 * }
 * 解释:
 *      a.可以用来修饰类的修饰符实际上不多,这里我们先不管(因为没有学习)
 *          现在我们默认类的修饰符,就两种:
 *              public修饰
 *              非public修饰
 *          一个Java文件下,可以允许有很多非public class,但是只能有一个public class,并且和文件名保持一致
 *          这些处在同一个java文件下的多个class,都是属于同包关系
 *          注/约定:
 *              在正常的开发中,我们一般只会在一个Java文件中,定义一个public class,很少定义非public class
 *              但是为了上课方便,查看代码更快捷,我们上课时会定义一个public class Demo作为测试的类,用来创建对象等
 *              定义非public class,作为被测试的类,实体类,比如学生类这种
 *
 *       b.类名遵循"大驼峰"式的命名规范,一般来说是一个名词,因为类是抽象全体对象的共性,而对象是程序世界的个体
 *          类名最好"见名知意"
 *       c.类体虽然是一对大括号,但是不要认为它是代码块,它不是代码块,其中的位置也不是局部位置
 *
 *       注意事项(重点):
 *          方法是不能嵌套定义的,方法必须独立的定义在类体中
 *          但是class类是可以嵌套定义的,可以将一个类定义到另一个类的类体中
 *          这称之为"内部类"
 *          但是内部类的语法,你还没有学习,现在定义内部类,你不会用.
 *          所以大家在定义类时,一定要看清楚类体的大括号,不要定义内部类,不要嵌套定义类
 *
 * 2.定义类中的结构
 * 某个对象具有它的属性,和它的行为
 *   既然类是创建对象的"模板"，那么就应该能够描述一种类别的全体对象，所以：
 *   类需要抽象出这种类型对象全体的属性共性,才能够描述所有对象的属性
 *   类需要抽象出这种类型对象全体的行为共性,才能够描述所有对象的行为
 *   在类中,用"成员变量"(member variable/field)描述全体对象的属性共性
 *   在类中,用"成员方法"(member method)描述全体对象的行为共性
 *
 * 定义成员变量:
 * 成员变量是什么?
 * 局部变量: 指的是定义在方法或者一个作用域内部,被作用域限制了作用范围的一个变量.局部变量就定义在局部位置
 * 成员变量: 指的是定义在成员位置的变量.
 * 成员位置: 指的是类体中,局部位置之外的位置,都称之为"成员位置"
 * 成员变量定义的语法:
 *      [修饰符列表] 数据类型 变量名;
 * 注: 修饰符列表这里先默认为空,不写,后面学习后再说.
 *
 * 定义成员方法:
 * 什么是成员方法?
 * 成员方法: 定义在类中成员位置,但是没有static修饰的方法是成员方法.
 * 语法:
 * [访问权限修饰符] 返回值类型 方法名(形参列表){
 *   // 方法体
 * }
 * 注:
 * 访问权限修饰符先默认为public
 * 其它的和我们之前讲的方法,一模一样定义,除了没有static修饰.
 *
 * 以上,一个类就定义完了,创建对象的模板就有了
 * -------------------
 * 如何创建对象呢?如果使用类这个模板创建对象呢?
 * 创建对象的位置:
 *      一般来说,都是在方法中创建对象,然后测试
 *      这里我们在Demo类中main方法创建对象并测试
 *
 * 创建对象的语法:
 *      类名 对象名 = new 类名();
 *
 * 创建对象以后,就可以去使用对象访问对象的属性和行为了.
 *
 * 成员变量和成员方法都是属于对象的,必须要创建对象,才能够访问它们.
 * 而且不同的对象,它们的成员变量和成员方法都是不一样的.
 *
 * 使用对象访问成员变量和方法:
 *      都是使用对象名访问
 *
 * 属于对象的成员变量是有默认值的,类似于数组动态初始化中的元素具有默认值.(因为它们都是对象中的元素)
 *
 *
 * 不同对象的成员方法有什么不一样呢?
 * 因为成员方法中,是可以访问自身成员变量的,而不同的对象,成员变量的取值是完全可以不同的,连带着成员方法也会不同
 *
 * -------
 * 最后,我们直接输出对象名
 * 得到一个字符串:
 * com.cskaoyan.javase.oop1._1basic.Student@1540e19d
 * 包名 + 类名 = 全限定类名
 * @ 后面跟的是一个十六进制的地址值
 * 所以对象名和数组名一样,都是一样引用,存储的都是堆上对象的地址
 * 注: 默认情况下,打印对象名是这样的,但是这个字符串是可以修改的,不是固定.
 *
 * @since 10:41
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    // 成员位置
    public static void main(String[] args) {
        // 局部位置
        // 创建Student类对象
        Student s = new Student();
        System.out.println(s.name);
        System.out.println(s.score);
        s.name = "长风";
        s.study();
        s.sleep();

        Student s2 = new Student();
        s2.name = "张三";
        System.out.println(s2.name);
        System.out.println(s.name);

        s2.sleep();
        s2.study();

        System.out.println("--------------------");
        System.out.println(s);
        System.out.println(s2);
        System.out.println(s == s2);
    }
}

// 定义学生类
class Student {
    // 抽取出全体学生对象属性的共性,得到成员变量
    String name;
    int age;
    int id;
    double score;

    // 抽取出全体学生对象行为的共性,得到成员方法
    public void study() {
        System.out.println("好好学习,天天向上");
    }

    public void sleep() {
        System.out.println(name + ",你这个年龄段,怎么睡得着?");
    }

}